import { spawn } from 'child_process';
import { createInterface } from 'readline';
import pino from 'pino';
import config from '../config.js';
import PushApi from './PushApi.js';

export default class FFmpegApi {

    static async toM4A(flvpath, m4apath) {
        const logger = pino({ transport: { target: 'pino-pretty' } });
        return new Promise((res, rej) => {
            const cmd = [
                '-y',
                '-i', flvpath,
                '-vn',
                '-codec', 'copy',
                m4apath
            ];
            let p = spawn('ffmpeg', cmd, {windowsHide:true});
            p.stdout.on('data', (data) => {
                logger.info('stdout: ' + data.toString());
            });
            p.stderr.on('data', (data) => {
                logger.info('stderr: ' + data.toString());
            });
            p.on('close', (code) => {
                logger.info(`flv转m4a结束,ffmpeg退出:code:${code}`);
                res();
            });
            p.on('error', (error) => {
                rej(error);
            });
        }).catch(ex => {
            logger.error(ex);
            PushApi.push('flv转m4a异常', ex.toString());
        });
    }

    static async toMP4(flvpath, mp4path) {
        const logger = pino({ transport: { target: 'pino-pretty' } });
        return new Promise((res, rej) => {
            const cmd = [
                '-y',
                '-i', flvpath,
                '-c', 'copy',
                '-movflags', 'faststart',
                mp4path
            ];
            let p = spawn('ffmpeg', cmd, {windowsHide:true});
            p.stdout.on('data', (data) => {
                logger.info('stdout: ' + data.toString());
            });
            p.stderr.on('data', (data) => {
                logger.info('stderr: ' + data.toString());
            });
            p.on('close', (code) => {
                logger.info(`ffmpeg退出:code:${code}`);
                res();
            });
            p.on('error', (error) => {
                rej(error);
            });
        }).catch(ex => {
            ctx.logger.error(ex);
            PushApi.push('flv转mp4异常', `${ex}`);
        });
    }

    static async toImageMP4(m4apath, mp4path) {
        const logger = pino({ transport: { target: 'pino-pretty' } });
        return new Promise((res, rej) => {
            const cmd = [
                '-r', '1',
                '-loop', '1',
                '-y', 
                '-i', config.up.background,
                '-i', m4apath,
                '-shortest',
                '-c:a', 'copy',
                '-c:v', 'libx264',
                '-b:v', '1k',
                mp4path
            ];
            let p = spawn('ffmpeg', cmd, {windowsHide:true});
            p.stdout.on('data', (data) => {
                logger.info('stdout: ' + data.toString());
            });
            p.stderr.on('data', (data) => {
                logger.info('stderr: ' + data.toString());
            });
            p.on('close', (code) => {
                logger.info(`生成ImageMp4结束,ffmpeg退出:code:${code}`);
                res();
            });
            p.on('error', (error) => {
                rej(error);
            });
        }).catch(ex => {
            logger.error(ex);
            PushApi.push('生成ImageMp4异常', `${ex}`);
        });
    }

    static async getDuration(path) {
        const logger = pino({ transport: { target: 'pino-pretty' } });
        return new Promise((res, rej) => {
            const cmd = [
                path,
            ];
            let p = spawn('ffprobe', cmd, {windowsHide:true});
            const rl = createInterface({
                input: p.stderr
            });
            let r = '';
            rl.on('line', line => {
                if (line.indexOf('Duration:') !== -1) {
                    r = line.match(/Duration: (.{11}),/)[1];
                }
            });
            p.on('close', (code) => {
                logger.info(`ffprobe退出:code:${code}`);
                res(r);
            });
            p.on('error', (error) => {
                rej(error);
            });
        }).catch(ex => {
            logger.error(ex);
            PushApi.push('ffprobe异常', ex.toString());
        });
    }
}